#include "StdAfx.h"
#include "SVMPredictor.h"
#include "..\FileHelper.h"

SVMPredictor::SVMPredictor(void)
:
m_svmModel( 0 )
{
}

SVMPredictor::~SVMPredictor(void)
{
	if( 0 != m_svmModel )
		svm_destroy_model( m_svmModel );
}

bool SVMPredictor::LoadModel(const char * modelFileName)
{
	if( !(FileNameHelper::ifExist(modelFileName)) )
		return false;

	struct svm_model* tempModel = svm_load_model( modelFileName ); // temporary pointer, no need to be released

	if( 0 != tempModel )
	{
		if( 0 != m_svmModel )
		{
			svm_destroy_model( m_svmModel );
			m_svmModel = 0;
		}
		m_svmModel = tempModel;
		return true;
	}
	else
	{
		return false;
	}
}

double SVMPredictor::Predict(const std::vector<double> & input, double *prob_estimates)
{
	if( 0 == m_svmModel )
	{
		throw std::exception( "SVM model hasn't been loaded" );
	}

	const int length = (int)input.size();
	struct svm_node* inputNode = new struct svm_node[length + 1]; // need one for index -1 as the tail node

	for( int i = 0; i < length; ++i )
	{
		inputNode[i].index = i + 1; // index starts from 1
		inputNode[i].value = input[i];
	}

	// the last node
	inputNode[length].index = -1;

	double label;
	if (NULL == prob_estimates)
	{
		label = svm_predict( m_svmModel, inputNode );
	}
	else
	{
		label = svm_predict_probability( m_svmModel, inputNode, prob_estimates);
	}

	delete[] inputNode;

	return label;
}
